package com.wanxing.sellerapp.seller.sdk.video

import android.content.ComponentName
import android.content.Context
import android.content.ServiceConnection
import android.os.IBinder
import android.text.TextUtils
import android.util.Log
import com.bket.bketCamera.BketCamera
import com.bket.bketCamera.BketCameraIface
import com.bket.bketlock.BketLockAdapter
import com.bket.bketlock.BketLockIface
import com.blankj.utilcode.util.ShellUtils
import com.wanxing.sellerapp.audio.AudioHelper
import com.wanxing.sellerapp.config.AppConfig
import com.wanxing.sellerapp.platform.Api
import com.wanxing.sellerapp.seller.callback.OpenDoorCallback
import com.wanxing.sellerapp.seller.events.ShowLogEvent
import com.wanxing.sellerapp.seller.sdk.enums.SellerTypeEnum
import com.wanxing.sellerapp.upload.Uploader
import com.wanxing.sellerapp.util.DateTimeUtil
import org.greenrobot.eventbus.EventBus
import java.util.Date
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean

class BaoJianVideoSeller(val context: Context) : IVideoSeller, BketLockIface{

    private val TAG = AppConfig.LOGTAG
    //  ①正常开锁开门关门关锁流程
    private val QUEUE_NORMAL_OPEN_CLOSE = "80671"
    //  ②正常开锁未开门关锁流程
    private val QUEUE_NORMAL_NOT_OPEN_DOOR = "8061"
    //  ③正常开锁开门关门超时
    private val QUEUE_NORMAL_NOT_CLOSE_DOOR = "80674"
    //  ④锁没开门开关门关锁流程（锁反馈异常情况）
    private val QUEUE_ERROR_OPEN_CLOSE = "8091"
    //  ⑥门或者锁异常无法开锁
    private val QUEUE_ERROR_CANNOT_OPEN_BROKEN = "82"
    //  ⑦门锁状态正常但是无法开锁
    private val QUEUE_ERROR_CANNOT_OPEN_FINE = "803"

    // 表示交易结束的状态
    private val ENDSTATUSCHANRS = "1234"

    private var powerState = true

    private val mBketCamera = BketCamera.getInstance(context.applicationContext)

    private lateinit var callback: VideoSellerCallback


    private val canOpenDoor = AtomicBoolean(true)

    private val singleTask = Executors.newSingleThreadScheduledExecutor()

    /**
     * 是否正在录视频
     */
    private var videoRecording = false

    /**
     * 是否需要上传
     */
    private var needupload = false

    private val doorStateQueue = StringBuilder()

    private val uploader = Uploader(context)

    private var orderId = ""
    private var date = ""

    private var openDoorCallback: OpenDoorCallback? = null

    private val connect = object : ServiceConnection {

        override fun onServiceConnected(name: ComponentName?, service: IBinder) {
            mBketCamera.setCallback(service,object : BketCameraIface {
                // 主摄像头录像完成
                override fun onHostVideoEnd(filename: String) {
                    if (needupload) {
                        EventBus.getDefault().post(ShowLogEvent("主摄录制完成,上传视频： $filename", orderId))
                        uploader.uploadVideo(filename)
                    } else{
                        EventBus.getDefault().post(ShowLogEvent("主摄录制完成,删除视频：$filename", orderId))
                        uploader.deleteVideo(filename)
                    }
                }
                // 辅摄像头录像完成
                override fun onSubVideoEnd(filename: String) {
                    if (needupload) {
                        EventBus.getDefault().post(ShowLogEvent("副摄录制完成,上传视频：$filename", orderId))
                        uploader.uploadVideo(filename)
                    } else{
                        EventBus.getDefault().post(ShowLogEvent("副摄录制完成,删除视频：$filename", orderId))
                        uploader.deleteVideo(filename)
                    }
                }
                // 主摄像头拍照结束
                override fun onHostTakePicEnd(filename: String) {}
                // 辅摄像头拍照结束
                override fun onSubTakePicEnd(filename: String) {}
                //打开摄像头，返回摄像头状态信息
                override fun onOpenCameraInfo(cameraInfo: String) {
                    videoRecording = true
                    needupload = false
                    val main = AppConfig.VIDEO_SAVE_PATH + date + "_" + orderId + "_h.mp4"
                    val sub = AppConfig.VIDEO_SAVE_PATH + date + "_" + orderId + "_s.mp4"
                    val rlt = mBketCamera.bketStartRecord(true, main, true, sub)
                    if (rlt == 0) {
                        EventBus.getDefault().post(ShowLogEvent("开始拍摄成功", orderId))
                    } else{
                        EventBus.getDefault().post(ShowLogEvent("开始拍摄失败", orderId))
                    }
                }
                //关闭摄像头，返回摄像头状态信息
                override fun onCloseCameraInfo(cameraInfo: String) {}
            })
            mBketCamera.bketOpenCamare()
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            Log.d(TAG, "onServiceDisconnected: $name")
            EventBus.getDefault().post(ShowLogEvent("连接视频服务成功", orderId))
        }

    }


    private val mLockAdapter = BketLockAdapter.getInstance("ttyS1", this)

    override fun init(callback: VideoSellerCallback): Boolean {
        this.callback = callback
        mLockAdapter.getLockModelVersion()
        uploader.run()
        ShellUtils.execCmd("setprop persist.video.outputh264 0", true)
        //TODO 这个机器配置放后台

//                mLockAdapter.confWaitTime(
//                    SellerConfig.HOLD_DOOR_OPEN_SECOND,
//                    SellerConfig.HOLD_DOOR_OPEN_SECOND_AFTER_OPEN
//                )
//                mLockAdapter.getDoorAndLockStatus()

        mBketCamera.bketSetSectionMode(3)
        singleTask.scheduleAtFixedRate({
           val c1s = mBketCamera.hostCameraIsOnline()
           val c2s = mBketCamera.subCameraIsOnline()
           try {
               Api.updateDeviceStatus(c1s, c2s, powerState)
           }catch (e: Exception) {
               Log.e(TAG,"同步设备状态失败", e)
           }
        },2000L, 10000L, TimeUnit.MILLISECONDS)
        return true
    }

    override fun canOpenDoor(): Boolean  {
        if (!canOpenDoor.get()) {
            AudioHelper.play(AudioHelper.SOUND_DEVICE_USING)
            return false
        }
        if (!mBketCamera.hostCameraIsOnline()) {
            AudioHelper.play(AudioHelper.SOUND_DEVICE_ERROR)
            return false
        }
        if (!mBketCamera.subCameraIsOnline()) {
            AudioHelper.play(AudioHelper.SOUND_DEVICE_ERROR)
            return false
        }
        return true
    }
    override fun openDoor(doorNo: Int): Boolean {
        // 没有订单号的补货
        doorStateQueue.clear()
        mLockAdapter.confQueryElectromagneticLock1Status()
        return true
    }

    override fun openDoor(doorNo: Int, orderId: String?, callback: OpenDoorCallback) { // ignore
        this.openDoorCallback = callback
        if (!mBketCamera.hostCameraIsOnline()){
            callback.videoOpenState("-1")
            EventBus.getDefault().post(ShowLogEvent("开锁失败，主摄不在线", orderId))
            return
        }
        if (!mBketCamera.subCameraIsOnline()){
            callback.videoOpenState("-2")
            EventBus.getDefault().post(ShowLogEvent("开锁失败，副摄不在线", orderId))
            return
        }
        this.orderId = orderId ?: ""
        this.date = DateTimeUtil.format(Date(),"yyMMdd")
        openDoor(doorNo)
    }

    override fun openDoor(doorNo: Int, orderId: String, date: String) {
        this.orderId = orderId
        this.date = date
        if (mBketCamera.hostCameraIsOnline() && mBketCamera.subCameraIsOnline() && canOpenDoor.get()) {
            doorStateQueue.clear()
            mLockAdapter.confQueryElectromagneticLock1Status()
            canOpenDoor.set(false)
            EventBus.getDefault().post(ShowLogEvent("开锁成功", orderId))
        }
        // 开门失败，更新订单状态
        else{
            if (!mBketCamera.hostCameraIsOnline()){
                AudioHelper.play(AudioHelper.SOUND_DEVICE_ERROR)
                EventBus.getDefault().post(ShowLogEvent("开锁失败，主摄不在线", orderId))
            } else if (!mBketCamera.subCameraIsOnline()){
                AudioHelper.play(AudioHelper.SOUND_DEVICE_ERROR)
                EventBus.getDefault().post(ShowLogEvent("开锁失败，副摄不在线", orderId))
            }else {
                EventBus.getDefault().post(ShowLogEvent("重复开门, 结束订单", orderId))
                //重复开门直接结束订单
                uploader.syncOrder(orderId, "2")
                AudioHelper.play(AudioHelper.SOUND_DEVICE_USING)
            }
        }
    }

    override fun closeDoor(doorNo: Int): Boolean {
        Log.w(TAG, "不支持主动关门")
        return true
    }
    override fun getType() = SellerTypeEnum.VIDEO
    override fun release() {
        uploader.release()
        mBketCamera.bketCloseCamera()
    }

    override fun onInfoLockModelVersion(versionInfo: String?) {
        Log.i(TAG, "versionInfo = $versionInfo")
    }

    override fun onInfoLockModelPowerStatus(status: String) {
        powerState = "01" == status
        EventBus.getDefault().post(ShowLogEvent("电源状态，$status", orderId))
    }

    private fun processLockState(lockNo: Int, status: String) {
        //返回开门状态
        if (status == "5" || status=="2" || status=="0") {
            openDoorCallback?.videoOpenState(status)
        }
        if (status == "5") {
            EventBus.getDefault().post(ShowLogEvent("重复开门，$status", orderId))
            callback.onRepeatUnlock(lockNo)
            return
        }
        val queue = doorStateQueue
        if (!queue.contains(status)) {
            queue.append(status)
            val que = queue.toString()
            if (!TextUtils.isEmpty(orderId) && status == "0" && !videoRecording) {
                EventBus.getDefault().post(ShowLogEvent("打开相机", orderId))
                val intent = mBketCamera.getServiceIntent(context);
                context.bindService(intent, connect, Context.BIND_AUTO_CREATE)
            }
            //结束流程
            if (ENDSTATUSCHANRS.contains(status)) {
                when (que) {
                    QUEUE_NORMAL_OPEN_CLOSE -> {
                        //正常关门需要传送视频
                        needupload = true
                        EventBus.getDefault().post(ShowLogEvent("正常关门，$que", orderId))
                        uploader.syncOrder(orderId, "1")
                    }
                    QUEUE_NORMAL_NOT_OPEN_DOOR -> {
                        EventBus.getDefault().post(ShowLogEvent("正常开锁没开门", orderId))
                        // 正常开锁没开门
                        uploader.syncOrder(orderId, "2")
                    }
                    QUEUE_NORMAL_NOT_CLOSE_DOOR -> {
                        EventBus.getDefault().post(ShowLogEvent("开门长时间未关门", orderId))
                        needupload = true
                        // 过了关门超时时间
                        uploader.syncOrder(orderId, "3")
                        //TODO 记录异常
                    }
                    QUEUE_ERROR_OPEN_CLOSE -> {
                        needupload = true
                        EventBus.getDefault().post(ShowLogEvent("锁没开门开关门关锁流程", orderId))
                        // 锁没开门开关门关锁流程（锁反馈异常情况）
                        uploader.syncOrder(orderId, "1")
                        //TODO 记录异常
                    }
                    QUEUE_ERROR_CANNOT_OPEN_BROKEN -> {
                        //锁异常无法开锁
                        EventBus.getDefault().post(ShowLogEvent("锁异常无法开锁", orderId))
                        uploader.syncOrder(orderId, "2")
                        //TODO 记录异常
                    }
                    QUEUE_ERROR_CANNOT_OPEN_FINE -> {
                        //门锁状态正常但是无法开锁
                        EventBus.getDefault().post(ShowLogEvent("门锁状态正常但是无法开锁", orderId))
                        uploader.syncOrder(orderId, "3")
                        //TODO 记录异常
                    }
                }
                EventBus.getDefault().post(ShowLogEvent("开关门流程结束->queue = ·$que·", orderId))
                if (videoRecording){
                    videoRecording = false
                    mBketCamera.bketStopRecord()
                    EventBus.getDefault().post(ShowLogEvent("结束录像", orderId))
                    mBketCamera.bketCloseCamera()
                    context.unbindService(connect)
                }
                canOpenDoor.set(true)
            }
        }
    }

    //status
    //0     锁和门状态均正常，可以开锁
    //1     正常关门关锁，开关门流程完成
    //2     锁和门状态有异常，不开锁，结束本次流程
    //3     开锁后，检测到锁的状态不正常，结束流程
    //4     开门时间超过了设定的最大超时时间（默认6min），结束流程
    //5     上一个流程没完成再次调用时，结束本次流程
    //6     锁已经正常打开，但是门没打开
    //7     锁已经正常打开，门也正常打开
    //8     收到调用指令confQueryElectromagneticLock1Status
    //9     开锁后锁反馈未开但是门开了，标记为异常开门交易事件
    override fun onInfoElectromagneticLock1Status(status: String) {
//        Log.d(TAG, "门1: status = $status")
        processLockState(1, status)
    }

    override fun onInfoElectromagneticLock2Status(status: String) {
//        Log.d(TAG, "门2： status = $status")
        processLockState(2, status)
    }

    override fun onInfoWatchDogStatus(status: String) {  // 0 关闭, 1 开启
        Log.i(TAG,"onInfoWatchDogStatus, status = $status")
    }

    override fun onInfoElectromagneticLockType(type: String) {
        // type = 0 类型1（星星 意林）低电平开锁 高电平关锁
        // type = 1 类型2（东控）高电平开锁 低电平关锁
        Log.i(TAG, "onInfoElectromagneticLockType: type = $type")
    }

    override fun onInfoCabinetDoorStatus(status: String) { // 0 门开, 1 门关
        Log.i(TAG, "onInfoCabinetDoorStatus: status = $status")
    }

    override fun onInfoExternalIOFun(type: String) {
        Log.i(TAG, "onInfoExternalIOFun: type = $type")
    }


    override fun onInfoTemperatureAndHumidity(temperatureAndHumidity: String) {
        Log.i(TAG, "onInfoTemperatureAndHumidity: $temperatureAndHumidity")
    }

    override fun onInfoDoorAndLockStatus(status: String) {
//        val lock1State = status.split(",")[0]
//        val door1State = status.split(",")[1]
//        val lock2State = status.split(",")[2]
//        val door2State = status.split(",")[3]
        Log.i(TAG, "onInfoDoorAndLockStatus: $status")
    }

    override fun onInfoStateChange(status: String) {
        if (status.split(",")[1] == "1") {
            Log.e(TAG,status)
            //异常开门
        }
    }
}